<?php
	function goto404(){
		exit(404);
	}

	function checkwclogin($mode=0,$callback='',$type=1){
	    //print_r($_SESSION);exit;
		if(!isset($_SESSION[APPID.'_userinfo'])){
			if($mode==1){
				return false;
			}else{
				if(!empty($callback)){
					$backurl=$callback;
				}else{
					$callback=$_SERVER['REQUEST_URI'];
				}
				return gotowechatlogin($callback,$mode,$type);
			}
		}else{
			return true;
		}
	}

	function gotologin($backurl='',$mode=0){
		$loginurl='/login.php';
		if(!empty($backurl)){
			$loginurl.='?backurl='.$backurl;
		}
		if($mode==2){
			return $loginurl;
		}else{
			header('Location:'.$loginurl);
		}
		exit;
	}

	function gotowechatlogin($backurl='',$mode=0,$type=0){
		$loginurl='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.APPID.'&redirect_uri=http://'.$_SERVER['HTTP_HOST'].'/libs/wechat/authorize.php';
		if(!empty($backurl)){
			$loginurl.=urlencode('?callback='.$backurl);
		}
		if($type==0){
			$scope='snsapi_base';
		}elseif($type==1){
			$scope='snsapi_userinfo';
		}
		$loginurl.='&response_type=code&scope='.$scope.'&state='.$type.'#wechat_redirect';
		if($mode==2){
			return $loginurl;
		}else{
			echo '<script language="javascript">window.top.location.href="'.$loginurl.'"</script>';
			//header('Location:'.$loginurl);
		}
		
		
		exit;
	}

	function getrandnum(){
		$yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K','L','M','N','O','P');
		$randn=$yCode[intval(date('Y'))-2011].strtoupper(dechex(date('m'))).date('d').substr(time(),-5).substr(microtime(),2,5).sprintf('%02d',rand(0,99));
		return $randn;
	}

	function getweixincontents($do,$set='',$method='GET',$mode=0,$domode=0,$gethead=0,$header=array(),$debug=0){
		if($domode==1){
			$dataurl=$do;
		}elseif($domode==2){
			checktoken($debug);
			$dataurl='https://api.weixin.qq.com/'.$do.'?access_token='.$_SESSION[APPID.'_access_token'];
		}else{
			$dataurl='https://api.weixin.qq.com/'.$do;
		}
		if($mode==0){
			checktoken($debug);
			$set['access_token']=$_SESSION[APPID.'_access_token'];
		}else if($mode==1){
			$set['appid']=APPID;
			$set['secret']=APPSECRET;
		}else if($mode==2){
			$set['access_token']=$_SESSION[APPID.'_user_access_token'];
		}
		if(!empty($set) && $method=='GET'){
			if(strpos($dataurl,'?')==false){
				$dataurl.='?';
			}else{
				$dataurl.='&';
			}
			$i=0;
			foreach($set as $key=>$value){
				if($i!=0){
					$dataurl.='&';
				}
				$dataurl.=$key.'='.$value;
				$i++;
			}
		}
		if($debug==1){
			echo $dataurl;
			if($method=='POST'){
				echo '<br>';
				print_r($set);
			}
		}
        $ch = curl_init();//初始化curl
        curl_setopt($ch, CURLOPT_URL,$dataurl);//抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER,$gethead);//设置header
        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);//设置header
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($ch, CURLOPT_TIMEOUT, 5);// 1s to timeout.
		if($method=='POST'){
			curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
			curl_setopt($ch, CURLOPT_POSTFIELDS, $set);
		}
        $data = curl_exec($ch);//运行curl
		if($debug==1){
			print_r($data);
		}
		if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '200' && $gethead==1) {
			$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
			$header=substr($data, 0, $headerSize);
			$header=explode("\r\n",$header);
			$headers=array();
			for($i=0;$i<count($header);$i++){
				if($i==0){
					$temp=explode(" ",$header[$i]);
				}else{
					$temp=explode(": ",$header[$i]);
				}
				$headers[$temp[0]]=$temp[1];
			}
			$data = substr($data, $headerSize);
		}
        curl_close($ch);
		if($data!='' && json_decode($data,1)!=''){
			$data=json_decode($data,1);
		}
		if(!empty($data['errcode']) && is_array($data)){
			global $errorcode;
			$data['errcn']=$errorcode[$data['errcode']];
			if($data['errcode']==40001){
				checktoken(0,1);
			}
		}
		if($gethead!=1){
			return $data;
		}else{
			$result['header']=$headers;
			$result['data']=$data;
			return $result;
		}
	}

	function getCurlFile($file){
		if (class_exists('CURLFile')){
			return curl_file_create($file['tmp_name'],$file['type'],$file['name']);
		}else{
			return '@'.$filename;
		}
	}

	//获取access token
	function checktoken($debug=0,$mode=0){
		global $db;
		$do='cgi-bin/token';
		$token=$db->get('tb_access_token','*',array('#expires_in[>]'=>'now()','order'=>'dt desc'));
		if(empty($token['access_token']) || $mode==1){
			$set=array('grant_type'=>'client_credential');
			$data=getweixincontents($do,$set,'GET',1);
			$db->insert('tb_access_token',array('access_token'=>$data['access_token'],'#expires_in'=>'DATE_ADD(now(),INTERVAL '.$data['expires_in'].' SECOND)','#dt'=>'now()'));
			$token=$db->get('tb_access_token','*',array('#expires_in[>]'=>'now()','order'=>'dt desc'));
		}
		if($debug==1){
			echo('access_token:'.$_SESSION[APPID.'_access_token'].'<br>');
			echo('expires_in:'.$_SESSION[APPID.'_expires_in'].'<br>');
			echo('time:'.time().'<br>');
		}
		$_SESSION[APPID.'_access_token']=$token['access_token'];
	}

	//微信消息验证
	function wechatvalid($mode=0){
		$echoStr = $_GET["echostr"];
        //valid signature , option
        if(checkSignature() || $_GET['encrypt_type']=='raw' || $_GET['encrypt_type']==''){
			if($mode==1){
				echo $echoStr;
				exit;
			}
        }else{
			echo 'valid Fail!';
			exit;
		}
	}

	//验证消息安全性
	function checkSignature(){
        // you must define TOKEN by yourself
        if (!defined("TOKEN")) {
            throw new Exception('TOKEN is not defined!');
        }
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];
		$tmpArr = array(TOKEN, $timestamp, $nonce);
        // use SORT_STRING rule
		sort($tmpArr, SORT_STRING);
		$tmpStr = implode( $tmpArr );
		$tmpStr = sha1( $tmpStr );

		if( $tmpStr == $signature ){
			return true;
		}else{
			return false;
		}
	}


	//接受消息
	function revicemsg($data){
		$data=$GLOBALS['HTTP_RAW_POST_DATA'];
		if($_GET['encrypt_type']!='raw' && $_GET['encrypt_type']!=''){
			$pc = new WXBizMsgCrypt(TOKEN, ENCODINGAESKEY, APPID);
        	$errCode = $pc->decryptMsg($_GET["msg_signature"], $_GET["timestamp"], $_GET["nonce"], $data, $msg);
			if ($errCode == 0) {
				return analyzerevicemsg($msg);
			} else {
				return $errCode;
			}
        }else{
			return analyzerevicemsg($data);
		}
	}


	//处理接受消息
	function analyzerevicemsg($text){
		global $db;
		$xml_tree = new DOMDocument();
		$xml_tree->loadXML($text);
		$data['FromUserName'] = $xml_tree->getElementsByTagName('FromUserName')->item(0)->nodeValue;
		$data['ToUserName'] = $xml_tree->getElementsByTagName('ToUserName')->item(0)->nodeValue;
		$data['CreateTime'] = $xml_tree->getElementsByTagName('CreateTime')->item(0)->nodeValue;
		$data['MsgType'] = $xml_tree->getElementsByTagName('MsgType')->item(0)->nodeValue;

		switch($data['MsgType']){
			//文本消息
			case 'text':
				$data['Content'] = $xml_tree->getElementsByTagName('Content')->item(0)->nodeValue;
				$data['MsgId'] = $xml_tree->getElementsByTagName('MsgId')->item(0)->nodeValue;
			break;
			//图片消息
			case 'image':
				$data['PicUrl'] = $xml_tree->getElementsByTagName('PicUrl')->item(0)->nodeValue;
				$data['MediaId'] = $xml_tree->getElementsByTagName('MediaId')->item(0)->nodeValue;
				$data['MsgId'] = $xml_tree->getElementsByTagName('MsgId')->item(0)->nodeValue;
			break;
			//语音消息
			case 'voice':
				$data['MediaId'] = $xml_tree->getElementsByTagName('MediaId')->item(0)->nodeValue;
				$data['Format'] = $xml_tree->getElementsByTagName('Format')->item(0)->nodeValue;
				$data['Recognition'] = $xml_tree->getElementsByTagName('Recognition')->item(0)->nodeValue;
				$data['MsgId'] = $xml_tree->getElementsByTagName('MsgId')->item(0)->nodeValue;
			break;
			//视频消息
			case 'video':
				$data['MediaId'] = $xml_tree->getElementsByTagName('MediaId')->item(0)->nodeValue;
				$data['ThumbMediaId'] = $xml_tree->getElementsByTagName('Format')->item(0)->nodeValue;
				$data['MsgId'] = $xml_tree->getElementsByTagName('MsgId')->item(0)->nodeValue;
			break;
			//小视频消息
			case 'shortvideo':
				$data['MediaId'] = $xml_tree->getElementsByTagName('MediaId')->item(0)->nodeValue;
				$data['ThumbMediaId'] = $xml_tree->getElementsByTagName('Format')->item(0)->nodeValue;
				$data['MsgId'] = $xml_tree->getElementsByTagName('MsgId')->item(0)->nodeValue;
			break;
			//地理位置消息
			case 'location':
				$data['Location_X'] = $xml_tree->getElementsByTagName('Location_X')->item(0)->nodeValue;
				$data['Location_Y'] = $xml_tree->getElementsByTagName('Location_Y')->item(0)->nodeValue;
				$data['Scale'] = $xml_tree->getElementsByTagName('Scale')->item(0)->nodeValue;
				$data['Label'] = $xml_tree->getElementsByTagName('Label')->item(0)->nodeValue;
				$data['MsgId'] = $xml_tree->getElementsByTagName('MsgId')->item(0)->nodeValue;
			break;
			//链接消息
			case 'link':
				$data['Title'] = $xml_tree->getElementsByTagName('Title')->item(0)->nodeValue;
				$data['Description'] = $xml_tree->getElementsByTagName('Description')->item(0)->nodeValue;
				$data['Url'] = $xml_tree->getElementsByTagName('Url')->item(0)->nodeValue;
				$data['MsgId'] = $xml_tree->getElementsByTagName('MsgId')->item(0)->nodeValue;
			break;
			//事件消息
			case 'event':
				$data['Event'] = $xml_tree->getElementsByTagName('Event')->item(0)->nodeValue;
				switch($data['Event']){
					//订阅
					case 'subscribe':
						$response=array();
						$response['FromUserName']=$data['ToUserName'];
						$response['ToUserName']=$data['FromUserName'];
						$response['Content']='SNAP专业测试帮您更好引导孩子成长，点击链接前往：<a href="http://测试链接">http://测试链接</a>';
						$response['MsgType']='text';
						return responsemsg($response);
					break;
					//取消订阅
					case 'unsubscribe':
					break;
					//用户已经关注公众号，扫描带参数二维码
					case 'SCAN':
					break;
					//点击菜单拉取消息
					case 'CLICK':
					break;
					//点击菜单跳转链接
					case 'VIEW':
					break;
				}
			break;
		}
		return 'success';
		$set=array('text'=>$text,'`from`'=>$data['FromUserName'],'type'=>$data['MsgType'],'#dt'=>'now()');
		if(!empty($data['Event'])){
			$set['event']=$data['Event'];
		}
		$db->insert('tb_revicemsg',$set);
	}

	//回复消息
	function responsemsg($response){
		$text='<xml>';
		foreach($response as $key=>$value){
			if(!is_array($value)){
				$text.='<'.$key.'><![CDATA['.$value.']]></'.$key.'>';
			}else{

			}
		}
		$text.='<CreateTime>'.time().'</CreateTime></xml>';

		if($_GET['encrypt_type']!='raw' && $_GET['encrypt_type']!=''){
			$pc = new WXBizMsgCrypt(TOKEN, ENCODINGAESKEY, APPID);
			$encryptMsg = '';
			$note=getrandnum();
			$errCode = $pc->encryptMsg($text, time(), getrandnum(), $encryptMsg);

			if ($errCode == 0) {
				return $encryptMsg;
			}else{
				return $errCode;
			}
		}
		return $text;
	}

	//添加客服帐号
	function addkf($account){
		$do='customservice/kfaccount/add';
		$data=getweixincontents($do,$account,'POST');
		return $data;
	}

	//修改客服帐号
	function updatekf($account){
		$do='customservice/kfaccount/update';
		$data=getweixincontents($do,$account,'POST');
		return $data;
	}

	//删除客服帐号
	function delkf($account){
		$do='customservice/kfaccount/del';
		$data=getweixincontents($do,$account);
		return $data;
	}

	//获取所有客服账号
	function getkf(){
		$do='cgi-bin/customservice/getkflist';
		$data=getweixincontents($do);
		return $data;
	}

	//主动发消息
	function sendmessagetouser($conetnt){
		$do='cgi-bin/message/custom/send';
		$set=array('touser'=>'o9PEswQumA7UcXShn1EvLEgKOQbQ','msgtype'=>'text','text'=>array('content'=>$conetnt));
		$data=getweixincontents($do,json_encode($set),'POST',0,2,0,array("Content-Type: application/json"),1);
		return $data;
	}

	//获取jsapi_ticket
	function getjsapi_ticket(){
		$do='cgi-bin/ticket/getticket';
		$set=array('type'=>'jsapi');
		$data=getweixincontents($do,$set,'GET');
		return $data;
	}

	//获取用户access_token和OPENID
	function checkuseraccesstoken($code,$debug=0,$mode=0){
		global $db;
		if(empty($_SESSION[APPID.'_user_access_token']) || time()>$_SESSION[APPID.'_user_expires_in'] || $mode==1){
			$do='sns/oauth2/access_token';
			$set=array('code'=>$code,'grant_type'=>'authorization_code');
			$data=getweixincontents($do,$set,'GET',1);
			if(!$data['error']){
				//$db->insert('tb_access_token',array('access_token'=>$data['access_token'],'expires_in'=>$data['expires_in'],'#dt'=>'now()','openid'=>$data['openid']));
				$_SESSION[APPID.'_user_access_token']=$data['access_token'];
				$_SESSION[APPID.'_user_expires_in']=time()+$data['expires_in'];
				$_SESSION[APPID.'_user_openid']=$data['openid'];
			}
		}
		if($debug==1){
			echo('useraccess_token:'.$_SESSION[APPID.'_user_access_token'].'<br>');
			echo('userexpires_in:'.$_SESSION[APPID.'_user_expires_in'].'<br>');
			echo('openid:'.$_SESSION[APPID.'_user_openid'].'<br>');
			echo('time:'.time().'<br>');
		}
		return $_SESSION[APPID.'_user_openid'];
	}

	//获取用户基本信息
	function getuserinfo($openid){
		$do='sns/userinfo';
		$do='cgi-bin/user/info';
		$set=array('openid'=>$openid,'lang'=>'zh_CN');
		$data=getweixincontents($do,$set,'GET',0);
		return $data;
	}

	//微信一键注册、登陆
	function wechatlogin($userinfo){
		$do='http://'.$_SERVER['HTTP_HOST'].'/getcontent.php?ac=member/wechatlogin';
		$set=array('openid'=>$userinfo['openid'],'nickname'=>$userinfo['nickname'],'headimgurl'=>$userinfo['headimgurl'],'ip'=>getip());
		$data=getweixincontents($do,$set,'POST',3,1);
		return $data;
	}

	//获取临时素材
	function mediaget($localid){
		$do='cgi-bin/media/get';
		$set=array('media_id'=>$localid);
		$data=getweixincontents($do,$set,'GET');
		return $data;
	}

	//创建预支付交易单
	function unifiedorder($param){
		$do='https://api.mch.weixin.qq.com/pay/unifiedorder';
		$set=array('appid'=>APPID,'mch_id'=>MCHID,'device_info'=>'WEB','nonce_str'=>getrandnum(),'body'=>$param['title'],'out_trade_no'=>$param['tradenumber'],'total_fee'=>$param['total']*100,'spbill_create_ip'=>getip(),'notify_url'=>'http://'.$_SERVER['HTTP_HOST'].'/notify.wxpay.php','trade_type'=>'JSAPI','openid'=>$_SESSION[APPID.'_userinfo']['openid']);
		$set['sign']=sign($set);
		$text='<xml>';
		foreach($set as $key=>$value){
			$text=$text.'<'.$key.'>'.$value.'</'.$key.'>';
		}
		$text.='</xml>';
		$xml=getweixincontents($do,$text,'POST',3,1);
		$xml_tree = new DOMDocument();
		$xml_tree->loadXML($xml);
		if($xml_tree->getElementsByTagName('return_code')->item(0)->nodeValue=='SUCCESS'){
			if(checksign($xml_tree)){
				if($xml_tree->getElementsByTagName('result_code')->item(0)->nodeValue=='SUCCESS'){
					$data['data']['tradenumber']=$param['tradenumber'];
					$prepayid=$xml_tree->getElementsByTagName('prepay_id')->item(0)->nodeValue;
					$data['data']['prepay_id']=$prepayid;
					$timestamp=time();
					$noncestr=make_nonceStr();
					$data['data']['timestamp']="$timestamp";
					$data['data']['noncestr']=$noncestr;
					$set=array('appId'=>APPID,'timeStamp'=>$timestamp,'nonceStr'=>$noncestr,'package'=>'prepay_id='.$prepayid,'signType'=>'MD5');
					$data['data']['sign']=sign($set);
				}else{
					$data['error'] = $xml_tree->getElementsByTagName('err_code')->item(0)->nodeValue.':'.$xml_tree->getElementsByTagName('err_code_des')->item(0)->nodeValue;
				}
			}else{
				$data['error'] = '错误的签名';
			}
		}else{
			$data['error'] = $xml_tree->getElementsByTagName('return_msg')->item(0)->nodeValue;
		}
		return $data;
	}

	function sign($set){
		$return='';
		ksort($set);
		foreach($set as $key=>$value){
			if(!empty($value) && $key!='sign'){
				$return.=$key.'='.$value.'&';
			}
		}
		$return.='key='.KEY;
		return strtoupper(md5($return));
	}

	function checksign($xml){
		$nodes =$xml->documentElement->childNodes;
		$set=array();
		foreach ($nodes as $elem ) {
			if($elem->nodeType==1){
				$set[$elem->nodeName]=$elem->nodeValue;
			}
		}
		if($set['sign']==sign($set)){
			return true;
		}else{
			return false;
		}
	}

	//新增临时素材
	function mediaupload($type,$file){
		//type: 媒体文件类型，分别有图片（image）、语音（voice）、视频（video）和缩略图（thumb）
		$do='cgi-bin/media/upload';
		$set=array('type'=>$type,'media'=>getCurlFile($file),'localid'=>getCurlFile($file));
		$data=getweixincontents($do,$set,'POST');
		return $data;
	}

	function uploadwechatimg($path,$file,$width='80',$height='80'){
		$error='';
		create($path);
		$filename = $path.'original_head.jpg';
		// 首先我们要确定文件存在并且可写。
		if (is_writable($path)){
			if ($handle = fopen($filename, 'wb')) {
				if(fwrite($handle, $file) === FALSE) {
					$error="不能写入到文件 ".$filename;
				}else{
					simgset($filename,$path.'head',$width,$height);
				}
			}else{
				$error="不能打开文件 ".$filename;
			}
			fclose($handle);
		} else {
			$error="文件 ".$filename." 不可写";
		}
		return $error;
	}
	function uploadwechatimg2($path,$file,$width='80',$height='80'){
		$error='';
		create($path);
		$filename = $path.md5(uniqid(rand())).'.jpg';
		// 首先我们要确定文件存在并且可写。
		if (is_writable($path)){
			if ($handle = fopen($filename, 'wb')) {
				if(fwrite($handle, $file) === FALSE) {
					$error="不能写入到文件 ".$filename;
				}else{
					simgset($filename,$path.'s'.date('YmdHis'),$width,$height);
				}
			}else{
				$error="不能打开文件 ".$filename;
			}
			fclose($handle);
		} else {
			$error="文件 ".$filename." 不可写";
		}
		return $error ? $error : $filename;
	}
	function simgset($source,$newname,$new_w=80,$new_h=80){
		$source_info = getimagesize($source);
		$source_w    = $source_info[0]; //获取宽
		$source_h    = $source_info[1]; //获取高
		$pre1=$source_w/$new_w;
		$pre2=$source_h/$new_h;
		if($pre1>$pre2){
			$pre=$pre2;
		}else{
			$pre=$pre1;
		}
		switch($source_info[2]){
			case 1 :$source_img = imagecreatefromgif($source);break;
			case 2 :$source_img = imagecreatefromjpeg($source);break;
			case 3 :$source_img = imagecreatefrompng($source);imagealphablending($source_img, FALSE);imagesavealpha($source_img,TRUE);break;
			default :return false;
		}
		$thumb = imagecreatetruecolor($new_w, $new_h);
		$back = imagecolorallocate($thumb,255,255,254);   //   填充的背景色
		imagefill($thumb,0,0,$back);
		$background_color=imagecolorresolve($thumb,255,255,254);
		imagecolortransparent($thumb,$background_color);
		imagecopyresized($thumb,$source_img,0,0,($source_w-$new_w*$pre)/2,($source_h-$new_h*$pre)/2,$new_w,$new_h,$new_w*$pre,$new_h*$pre);
		$ftype=substr($source,strrpos($source,".")+1,strlen($source));
		switch($source_info[2]){
			case 1 :imagegif($thumb,$newname.'.'.$ftype);break;
			case 2 :imagejpeg($thumb,$newname.'.'.$ftype);break;
			case 3 :imagepng($thumb,$newname.'.'.$ftype);break;
		}
		imagedestroy ($thumb);
	}

	function make_nonceStr(){
		$codeSet = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
		for ($i = 0; $i<16; $i++) {
			$codes[$i] = $codeSet[mt_rand(0, strlen($codeSet)-1)];
		}
		$nonceStr = implode($codes);
		return $nonceStr;
	}

	function make_signature($nonceStr,$timestamp,$jsapi_ticket,$url){
		$tmpArr = array(
		'noncestr' => $nonceStr,
		'timestamp' => $timestamp,
		'jsapi_ticket' => $jsapi_ticket,
		'url' => $url
		);
		ksort($tmpArr, SORT_STRING);
		$string1 = http_build_query( $tmpArr );
		$string1 = urldecode( $string1 );
		$signature = sha1( $string1 );
		return $signature;
	}

	function filterEmoji($str){
    $str = preg_replace_callback(
	        '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);
     return $str;
 }
?>
